#include "ClientContext.h"
#include "Buffer.h"

ClientContext::ClientContext( void )
: m_pRecvLock( NULL )
, m_pSendLock( NULL )
, m_pStateLock( NULL )
, m_eState( STATE_SHUTDOWN )
{
	m_pRecvLock = new CLock;
	m_pSendLock = new CLock;
	m_pStateLock = new CLock;
}

ClientContext::~ClientContext( void )
{
	SAFE_DELETE( m_pSendLock );
	SAFE_DELETE( m_pRecvLock );
	SAFE_DELETE( m_pStateLock );
}

void ClientContext::SetSocket( SOCKET socket )
{
	m_socketAccept = socket;
}

void ClientContext::PushSendBuffer( SendBuff *pBuffer )
{
	AutoLock lock( m_pSendLock );

	if( !pBuffer )
		return ;

	m_aSendBufferList.push_back( pBuffer );
}

void ClientContext::PushFrontSendBuffer( SendBuff* pBuffer )
{
	AutoLock lock( m_pSendLock );

	if( !pBuffer )
		return ;

	m_aSendBufferList.push_front( pBuffer );
}

SendBuff* ClientContext::PopSendBuffer()
{
	AutoLock lock( m_pSendLock );

	SendBuff* pBuffer = m_aSendBufferList.front();
	m_aSendBufferList.pop_front();

	return pBuffer;
}

void ClientContext::PushRecvBuffer( Buffer* pBuffer )
{
	AutoLock lock( m_pRecvLock );
	if( !pBuffer )
		return ;

	m_aRecvBufferList.push_back( pBuffer );
}

Buffer* ClientContext::PopRecvBuffer()
{
	AutoLock lock( m_pRecvLock );

	Buffer* pBuffer = m_aRecvBufferList.front();
	m_aRecvBufferList.pop_front();

	return pBuffer;
}

void ClientContext::ClientUp()
{
	AutoLock sLock( m_pRecvLock );
	IterBufferList itr = m_aRecvBufferList.begin();
	IterBufferList iEnd = m_aRecvBufferList.end();
	for( ; itr != iEnd; ++itr )
	{
		Buffer* pBuffer = ( *itr );
		SAFE_DELETE( pBuffer );
	}
	m_aRecvBufferList.clear();

	AutoLock rLock( m_pRecvLock );

	IterSendBuffList iSend = m_aSendBufferList.begin();
	IterSendBuffList iSendEnd = m_aSendBufferList.end();
	for( ; iSend != iSendEnd; ++iSend )
	{
		SendBuff* pBuffer = ( *iSend );
		SAFE_DELETE( pBuffer );
	}
	m_aSendBufferList.clear();

	if( INVALID_SOCKET == GetSocket() )
	{
		closesocket( m_socketAccept );
		m_socketAccept = INVALID_SOCKET;
	}
}

void ClientContext::SetSockAddr( std::string sClientIP )
{
	m_sClientIP = sClientIP;
}

void ClientContext::SetState( CONTEXT_STATE eState )
{
	m_pStateLock->Lock();
	m_eState = eState;
	m_pStateLock->UnLock();
}

CONTEXT_STATE ClientContext::GetState()
{
	AutoLock lock( m_pStateLock );
	return m_eState;
}
